@profullstack/coinpay 0.5.7 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/coinpay.js +107 -1
- package/package.json +1 -1
- package/src/index.js +3 -0
- package/src/reputation.d.ts +33 -0
- package/src/reputation.js +78 -0
package/bin/coinpay.js
CHANGED
|
@@ -222,6 +222,9 @@ ${colors.cyan}Commands:${colors.reset}
|
|
|
222
222
|
submit Submit a task receipt
|
|
223
223
|
query <agent-did> Query agent reputation
|
|
224
224
|
credential <id> Get credential details
|
|
225
|
+
credentials [did] List all credentials for a DID
|
|
226
|
+
receipts [did] List all task receipts for a DID
|
|
227
|
+
badge [did] Get embeddable reputation badge URL
|
|
225
228
|
verify <id> Verify a credential
|
|
226
229
|
revocations List revoked credentials
|
|
227
230
|
|
|
@@ -1785,9 +1788,112 @@ async function handleReputation(subcommand, args, flags) {
|
|
|
1785
1788
|
break;
|
|
1786
1789
|
}
|
|
1787
1790
|
|
|
1791
|
+
case 'credentials': {
|
|
1792
|
+
const did = args[0];
|
|
1793
|
+
if (!did) {
|
|
1794
|
+
// Try to get own DID
|
|
1795
|
+
const { getMyDid } = await import('../src/reputation.js');
|
|
1796
|
+
const myDid = await getMyDid(client);
|
|
1797
|
+
if (!myDid?.did) {
|
|
1798
|
+
print.error('Usage: coinpay reputation credentials <did>');
|
|
1799
|
+
print.info('Or claim a DID first: coinpay reputation did claim');
|
|
1800
|
+
process.exit(1);
|
|
1801
|
+
}
|
|
1802
|
+
const { getCredentials } = await import('../src/reputation.js');
|
|
1803
|
+
const result = await getCredentials(client, myDid.did);
|
|
1804
|
+
if (result.credentials && result.credentials.length > 0) {
|
|
1805
|
+
print.success(`${result.credentials.length} credential(s) for ${myDid.did}:`);
|
|
1806
|
+
for (const cred of result.credentials) {
|
|
1807
|
+
print.info(` ${cred.id} | ${cred.credential_type} | ${cred.revoked ? '❌ Revoked' : '✅ Active'} | ${new Date(cred.issued_at).toLocaleDateString()}`);
|
|
1808
|
+
}
|
|
1809
|
+
} else {
|
|
1810
|
+
print.info('No credentials found. Complete escrow transactions to earn credentials.');
|
|
1811
|
+
}
|
|
1812
|
+
if (flags.json) print.json(result);
|
|
1813
|
+
} else {
|
|
1814
|
+
const { getCredentials } = await import('../src/reputation.js');
|
|
1815
|
+
const result = await getCredentials(client, did);
|
|
1816
|
+
if (result.credentials && result.credentials.length > 0) {
|
|
1817
|
+
print.success(`${result.credentials.length} credential(s) for ${did}:`);
|
|
1818
|
+
for (const cred of result.credentials) {
|
|
1819
|
+
print.info(` ${cred.id} | ${cred.credential_type} | ${cred.revoked ? '❌ Revoked' : '✅ Active'} | ${new Date(cred.issued_at).toLocaleDateString()}`);
|
|
1820
|
+
}
|
|
1821
|
+
} else {
|
|
1822
|
+
print.info('No credentials found for this DID.');
|
|
1823
|
+
}
|
|
1824
|
+
if (flags.json) print.json(result);
|
|
1825
|
+
}
|
|
1826
|
+
break;
|
|
1827
|
+
}
|
|
1828
|
+
|
|
1829
|
+
case 'receipts': {
|
|
1830
|
+
const did = args[0];
|
|
1831
|
+
if (!did) {
|
|
1832
|
+
const { getMyDid } = await import('../src/reputation.js');
|
|
1833
|
+
const myDid = await getMyDid(client);
|
|
1834
|
+
if (!myDid?.did) {
|
|
1835
|
+
print.error('Usage: coinpay reputation receipts <did>');
|
|
1836
|
+
print.info('Or claim a DID first: coinpay reputation did claim');
|
|
1837
|
+
process.exit(1);
|
|
1838
|
+
}
|
|
1839
|
+
const { getReceipts } = await import('../src/reputation.js');
|
|
1840
|
+
const result = await getReceipts(client, myDid.did);
|
|
1841
|
+
if (result.receipts && result.receipts.length > 0) {
|
|
1842
|
+
print.success(`${result.receipts.length} receipt(s) for ${myDid.did}:`);
|
|
1843
|
+
for (const r of result.receipts) {
|
|
1844
|
+
print.info(` ${r.receipt_id} | ${r.outcome} | $${r.amount || 0} ${r.currency || ''} | ${new Date(r.created_at).toLocaleDateString()}`);
|
|
1845
|
+
}
|
|
1846
|
+
} else {
|
|
1847
|
+
print.info('No receipts found. Complete escrow transactions to generate receipts.');
|
|
1848
|
+
}
|
|
1849
|
+
if (flags.json) print.json(result);
|
|
1850
|
+
} else {
|
|
1851
|
+
const { getReceipts } = await import('../src/reputation.js');
|
|
1852
|
+
const result = await getReceipts(client, did);
|
|
1853
|
+
if (result.receipts && result.receipts.length > 0) {
|
|
1854
|
+
print.success(`${result.receipts.length} receipt(s) for ${did}:`);
|
|
1855
|
+
for (const r of result.receipts) {
|
|
1856
|
+
print.info(` ${r.receipt_id} | ${r.outcome} | $${r.amount || 0} ${r.currency || ''} | ${new Date(r.created_at).toLocaleDateString()}`);
|
|
1857
|
+
}
|
|
1858
|
+
} else {
|
|
1859
|
+
print.info('No receipts found for this DID.');
|
|
1860
|
+
}
|
|
1861
|
+
if (flags.json) print.json(result);
|
|
1862
|
+
}
|
|
1863
|
+
break;
|
|
1864
|
+
}
|
|
1865
|
+
|
|
1866
|
+
case 'badge': {
|
|
1867
|
+
const did = args[0];
|
|
1868
|
+
if (!did) {
|
|
1869
|
+
const { getMyDid } = await import('../src/reputation.js');
|
|
1870
|
+
const myDid = await getMyDid(client);
|
|
1871
|
+
if (!myDid?.did) {
|
|
1872
|
+
print.error('Usage: coinpay reputation badge <did>');
|
|
1873
|
+
process.exit(1);
|
|
1874
|
+
}
|
|
1875
|
+
const { getBadgeUrl } = await import('../src/reputation.js');
|
|
1876
|
+
const url = getBadgeUrl(client.baseUrl || 'https://coinpayportal.com', myDid.did);
|
|
1877
|
+
print.success('Badge URL:');
|
|
1878
|
+
print.info(` ${url}`);
|
|
1879
|
+
print.info('');
|
|
1880
|
+
print.info('Markdown embed:');
|
|
1881
|
+
print.info(` `);
|
|
1882
|
+
} else {
|
|
1883
|
+
const { getBadgeUrl } = await import('../src/reputation.js');
|
|
1884
|
+
const url = getBadgeUrl(client.baseUrl || 'https://coinpayportal.com', did);
|
|
1885
|
+
print.success('Badge URL:');
|
|
1886
|
+
print.info(` ${url}`);
|
|
1887
|
+
print.info('');
|
|
1888
|
+
print.info('Markdown embed:');
|
|
1889
|
+
print.info(` `);
|
|
1890
|
+
}
|
|
1891
|
+
break;
|
|
1892
|
+
}
|
|
1893
|
+
|
|
1788
1894
|
default:
|
|
1789
1895
|
print.error(`Unknown reputation command: ${subcommand}`);
|
|
1790
|
-
print.info('Available: submit, query, credential, verify, revocations, did');
|
|
1896
|
+
print.info('Available: submit, query, credential, credentials, receipts, badge, verify, revocations, did');
|
|
1791
1897
|
process.exit(1);
|
|
1792
1898
|
}
|
|
1793
1899
|
}
|
package/package.json
CHANGED
package/src/index.js
CHANGED
package/src/reputation.d.ts
CHANGED
|
@@ -70,6 +70,39 @@ export function getCredential(client: CoinPayClient, credentialId: string): Prom
|
|
|
70
70
|
export function verifyCredential(client: CoinPayClient, credential: { credential_id: string }): Promise<{ valid: boolean; reason?: string }>;
|
|
71
71
|
export function getRevocationList(client: CoinPayClient): Promise<{ success: boolean; revoked_credentials: string[]; revocations: Array<Record<string, unknown>> }>;
|
|
72
72
|
|
|
73
|
+
// CPTL Phase 2
|
|
74
|
+
|
|
75
|
+
export type ActionCategory =
|
|
76
|
+
| 'economic.transaction' | 'economic.dispute' | 'economic.refund'
|
|
77
|
+
| 'productivity.task' | 'productivity.application' | 'productivity.completion'
|
|
78
|
+
| 'identity.profile_update' | 'identity.verification'
|
|
79
|
+
| 'social.post' | 'social.comment' | 'social.endorsement'
|
|
80
|
+
| 'compliance.incident' | 'compliance.violation';
|
|
81
|
+
|
|
82
|
+
export interface ActionReceiptInput extends ReceiptInput {
|
|
83
|
+
action_category?: ActionCategory;
|
|
84
|
+
action_type?: string;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export interface TrustVector {
|
|
88
|
+
E: number;
|
|
89
|
+
P: number;
|
|
90
|
+
B: number;
|
|
91
|
+
D: number;
|
|
92
|
+
R: number;
|
|
93
|
+
A: number;
|
|
94
|
+
C: number;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export interface TrustProfileResult {
|
|
98
|
+
trust_vector: TrustVector | null;
|
|
99
|
+
reputation: ReputationResult | null;
|
|
100
|
+
computed_at: string | null;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export function submitActionReceipt(client: CoinPayClient, receipt: ActionReceiptInput): Promise<{ success: boolean; receipt?: Record<string, unknown>; error?: string }>;
|
|
104
|
+
export function getTrustProfile(client: CoinPayClient, agentDid: string): Promise<TrustProfileResult>;
|
|
105
|
+
|
|
73
106
|
export interface DidInfo {
|
|
74
107
|
did: string;
|
|
75
108
|
public_key: string;
|
package/src/reputation.js
CHANGED
|
@@ -102,3 +102,81 @@ export async function linkDid(client, { did, publicKey, signature }) {
|
|
|
102
102
|
}),
|
|
103
103
|
});
|
|
104
104
|
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Get all credentials for a DID
|
|
108
|
+
* @param {import('./client.js').CoinPayClient} client
|
|
109
|
+
* @param {string} did - The DID to query credentials for
|
|
110
|
+
* @returns {Promise<Object>}
|
|
111
|
+
*/
|
|
112
|
+
export async function getCredentials(client, did) {
|
|
113
|
+
return client.request(`/reputation/credentials?did=${encodeURIComponent(did)}`);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Get all task receipts for a DID
|
|
118
|
+
* @param {import('./client.js').CoinPayClient} client
|
|
119
|
+
* @param {string} did - The DID to query receipts for
|
|
120
|
+
* @returns {Promise<Object>}
|
|
121
|
+
*/
|
|
122
|
+
export async function getReceipts(client, did) {
|
|
123
|
+
return client.request(`/reputation/receipts?did=${encodeURIComponent(did)}`);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// ═══════════════════════════════════════════════════════════
|
|
127
|
+
// CPTL Phase 2 — Action Receipts & Trust Profile
|
|
128
|
+
// ═══════════════════════════════════════════════════════════
|
|
129
|
+
|
|
130
|
+
const CANONICAL_CATEGORIES = [
|
|
131
|
+
'economic.transaction', 'economic.dispute', 'economic.refund',
|
|
132
|
+
'productivity.task', 'productivity.application', 'productivity.completion',
|
|
133
|
+
'identity.profile_update', 'identity.verification',
|
|
134
|
+
'social.post', 'social.comment', 'social.endorsement',
|
|
135
|
+
'compliance.incident', 'compliance.violation',
|
|
136
|
+
];
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Submit an action receipt with schema validation
|
|
140
|
+
* @param {import('./client.js').CoinPayClient} client
|
|
141
|
+
* @param {Object} receipt - Action receipt with action_category
|
|
142
|
+
* @returns {Promise<Object>}
|
|
143
|
+
*/
|
|
144
|
+
export async function submitActionReceipt(client, receipt) {
|
|
145
|
+
// Validate action_category if provided
|
|
146
|
+
if (receipt.action_category && !CANONICAL_CATEGORIES.includes(receipt.action_category)) {
|
|
147
|
+
throw new Error(`Invalid action_category: ${receipt.action_category}. Must be one of: ${CANONICAL_CATEGORIES.join(', ')}`);
|
|
148
|
+
}
|
|
149
|
+
// Default action_category
|
|
150
|
+
if (!receipt.action_category) {
|
|
151
|
+
receipt = { ...receipt, action_category: 'economic.transaction' };
|
|
152
|
+
}
|
|
153
|
+
return client.request('/reputation/receipt', {
|
|
154
|
+
method: 'POST',
|
|
155
|
+
body: JSON.stringify(receipt),
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Get trust profile (trust vector) for an agent DID
|
|
161
|
+
* @param {import('./client.js').CoinPayClient} client
|
|
162
|
+
* @param {string} agentDid
|
|
163
|
+
* @returns {Promise<Object>} Trust vector { E, P, B, D, R, A, C }
|
|
164
|
+
*/
|
|
165
|
+
export async function getTrustProfile(client, agentDid) {
|
|
166
|
+
const result = await client.request(`/reputation/agent/${encodeURIComponent(agentDid)}/reputation`);
|
|
167
|
+
return {
|
|
168
|
+
trust_vector: result.trust_vector || null,
|
|
169
|
+
reputation: result.reputation || null,
|
|
170
|
+
computed_at: result.computed_at || null,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Get the badge URL for a DID
|
|
176
|
+
* @param {string} baseUrl - The CoinPayPortal base URL
|
|
177
|
+
* @param {string} did - The DID
|
|
178
|
+
* @returns {string} Badge SVG URL
|
|
179
|
+
*/
|
|
180
|
+
export function getBadgeUrl(baseUrl, did) {
|
|
181
|
+
return `${baseUrl}/api/reputation/badge/${encodeURIComponent(did)}`;
|
|
182
|
+
}
|